# 练习1:
# 现有如下代码， 会输出什么：
print('-'*20, '练习1', '-'*20)
# class People(object):
#   __name = "luffy"
#   __age = 18
#
# p1 = People()
# print(p1.__name, p1.__age)

# 答：无法打印类的私有对象
# --------------------------------------------------------------------------
# 练习2:
# 编写程序, 编写一个学生类, 要求有一个计数器的属性, 统计总共实例化了多少个学生.
print('-'*20, '练习2', '-'*20)
class Student(object):
    __count = 0
    def __new__(cls, *args, **kwargs):
        cls.__count += 1
        return object.__new__(cls)

    @classmethod
    def count(cls):
        print('there is %d students'%cls.__count)

s1 = Student()
Student.count()
s2 = Student()
Student.count()
# -----------------------------------------------------------------------
# 练习3:
# 编写程序, A 继承了 B, 俩个类都实现了 handle 方法, 在 A 中的 handle 方法中调用 B 的 handle 方法
print('-'*20, '练习3', '-'*20)
class B(object):
    def handle(self):
        print('B handle')

class A(B):
    def handle(self):
        super().handle()
        print('A handle')

A().handle()

# -----------------------------------------------------------------------
# 练习4:
# 模仿王者荣耀定义两个英雄类
# 要求：
#
# 英雄需要有昵称、攻击力、生命值等属性；
# 实例化出两个英雄对象；
# 英雄之间可以互殴，被殴打的一方掉血，血量小于0则判定为死亡(提示:这里是函数)
print('-'*20, '练习4', '-'*20)
class Hero(object):
    def __init__(self, name, atk, life):
        self.name = name
        self.atk = atk
        self.life = life

    def is_live(self):
        return self.life > 0

t = Hero('Tom', 15, 100)
j = Hero('Jerry', 5, 200)

while True:
    j.life -= t.atk
    if not j.is_live():
        print('%s is dead'%j.name)
        break
    t.life -= j.atk
    if not t.is_live():
        print('%s is dead'%t.name)
        break

# ------------------------------------------------------------------------
# 练习5:
# 请编写一段符合多态特性的代码.
print('-'*20, '练习5', '-'*20)
class Archer(object):
    def attack(self):
        print('xuxuxu')

class Warrior(object):
    def attack(self):
        print('kakaka')

def do_attack(hero):
    hero.attack()

a = Archer()
w = Warrior()
do_attack(a)
do_attack(w)

# -------------------------------------------------------------------
# 练习6:下面三种实现单例的方法,哪一种写法是正确的,为什么
print('-'*20, '练习6', '-'*20)
class Single(object):
    __instance = None
    def __new__(cls):
        if not cls.__instance:
            #写法一
            # cls.__instance = Single() #

            # 写法二
            cls.__instance = super(Single, cls).__new__(cls)

            # 写法三
            # cls.__instance = object.__new__(cls)

        return cls.__instance
A = Single()
B = Single()
print(id(A))
print(id(B))

# 答：
# 写法一会导致递归创建对象；
# 写法三与老师教的相同，应为正确答案；
# 写法二也能达成单例的效果；
